home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / wildcard.c < prev   
Encoding:
C/C++ Source or Header  |  1999-10-20  |  9.3 KB  |  295 lines

  1. /* cfengine for GNU
  2.  
  3.         Copyright (C) 1995
  4.         Free Software Foundation, Inc.
  5.  
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.  
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23.  
  24. */
  25.  
  26.  
  27. #include "cf.defs.h"
  28. #include "cf.extern.h"
  29.  
  30.  
  31. /*************************************************************************/
  32. /* WILDCARD TOOLKIT : Level 0                                            */
  33. /*************************************************************************/
  34.  
  35. #define nomatch         0
  36. #define match           1
  37. #define maxlen          20
  38. #define startofstrings  10
  39. #define middleofstrings 11
  40. #define endofstrings    12
  41.  
  42. #define Wild(c)  (c == '*' || c == '?') ? true : false
  43.  
  44. #include <string.h>
  45.  
  46.  
  47. /*************************************************************************/
  48.  
  49. IsWildCard (str)
  50.  
  51. char *str;
  52.  
  53. {
  54. return (strchr(str,'?') || strchr(str,'*'));
  55.  
  56. /*************************************************************************/
  57.  
  58.  
  59.    WildMatch (wildptr,cmpptr)
  60.  
  61.    char *wildptr, *cmpptr;
  62.  
  63.    { char buffer[bufsize];
  64.      char *AfterSubString();
  65.      int i, status = startofstrings;
  66.      char lastwild = '\0';
  67.  
  68.    Debug1("WildMatch(%s,%s)\n",wildptr,cmpptr);
  69.      
  70.    if (strstr(wildptr,"*") == NULL && strstr(wildptr,"?") == NULL)
  71.       {
  72.       return (! strcmp(wildptr,cmpptr));
  73.       }
  74.  
  75.   while (true)
  76.       {
  77.       while (*wildptr == '?')                                /* 1 */
  78.          {
  79.          wildptr++;
  80.          cmpptr++;
  81.          if ((*cmpptr == '\0') && (*wildptr != '\0'))        /* 2 */
  82.             {
  83.             return(nomatch);
  84.             }
  85.          lastwild = '?';
  86.          status = middleofstrings;
  87.          }
  88.  
  89.       if (*wildptr == '\0' && *cmpptr == '\0')                /* 3 */
  90.          {
  91.          return(match);
  92.          }
  93.       else if (*wildptr == '\0')                              /* 4 */
  94.          {
  95.          return(nomatch);
  96.          }
  97.  
  98.       if (*wildptr == '*')                                    /* 5 */
  99.          {
  100.          while (*wildptr == '*')                              /* 6 */
  101.             {
  102.             wildptr++;
  103.             }
  104.          if (*wildptr == '\0')                                /* 7 */
  105.             {
  106.             if (*cmpptr == '\0')                              /* 8 */
  107.                {
  108.                return(nomatch);
  109.                }
  110.             else
  111.                {
  112.                return(match);
  113.                }
  114.             }
  115.  
  116.          cmpptr++;                                            /* 9 */
  117.          status = middleofstrings;
  118.          lastwild = '*';
  119.          }
  120.  
  121.       for (i = 0; !(Wild(*wildptr) || *wildptr == '\0'); i++) /* 10 */
  122.          {
  123.          buffer[i] = *wildptr++;
  124.          if (*wildptr == '\0')                                /* 11 */
  125.             {
  126.             status = endofstrings;
  127.             }
  128.          }
  129.  
  130.       buffer[i] = '\0';
  131.  
  132.       if ((cmpptr = AfterSubString(cmpptr,buffer,status,lastwild)) == NULL)
  133.          {
  134.          return(nomatch);                                      /* 12 */
  135.          }
  136.  
  137.       status = middleofstrings;
  138.       }
  139.    }
  140.  
  141. /******************************************************************/
  142. /* Wildcard Toolkit : Level 1                                     */
  143. /******************************************************************/
  144.  
  145.   char *AfterSubString(big,small,status,lastwild)
  146.  
  147.    /* If the last wildcard was a ? then this just tries to      */
  148.    /* match the substrings from the present position, otherwise */
  149.    /* looks for next occurrance of small within big and returns */
  150.    /* a pointer to the next character in big after small or     */
  151.    /* NULL if there is no string found to match                 */
  152.    /* If end of strings is signalled, make sure that the string */
  153.    /* is tied to the end of big. This makes sure that there is  */
  154.    /* correct alignment with end of string marker.              */
  155.  
  156.    char *big,*small;
  157.    int status;
  158.    char lastwild;
  159.  
  160.    { char *bigptr;
  161.  
  162.    if (strlen(small) > strlen(big))                       /* 13 */
  163.       {
  164.       return(NULL);
  165.       }
  166.  
  167.    if (lastwild == '?')                                   /* 14 */
  168.       {
  169.       if (strncmp(big,small,strlen(small)) == 0)
  170.          {
  171.          return(big+strlen(small));
  172.          }
  173.       else
  174.          {
  175.          return(NULL);
  176.          }
  177.       }
  178.  
  179.    if (status == endofstrings)                             /* 15 */
  180.       {
  181.       big = big + strlen(big) - strlen(small);
  182.       }
  183.  
  184.    for (bigptr = big; *bigptr != '\0'; ++bigptr)           /* 16 */
  185.       {
  186.       if (strncmp(bigptr,small,strlen(small)) == 0)
  187.          {
  188.          return(bigptr+strlen(small));
  189.          }
  190.  
  191.       if (status == startofstrings)                        /* 17 */
  192.          {
  193.          return(NULL);
  194.          }
  195.       }
  196.  
  197.    return(NULL);                                           /* 18 */
  198.    }
  199.  
  200. /******************************************************************
  201.  
  202. Comments :
  203.  
  204. 1. ? Matches a single character. Skip over with pointers.
  205. 2. Check that the compare string hasn't run out too soon.
  206. 3. If the wild-match is complete return MATCH!
  207. 4. other wise check that the wild card string hasn't run out
  208.    too soon.
  209.  
  210. 5. * Matches any string.
  211. 6. Skip over any *'s in the wildcard string and leave pointer
  212.    on the first character after.
  213. 7. If the last character in the wildstring is *, match any
  214.    remaining characters...
  215. 8. ...except no string at all. e.g. xyz* doesn't match xyz
  216. 9. Advancing this pointer by one, prevents * from matching
  217.    the null string even when the pointers haven't reached
  218.    the end of the string (so that the match is not complete).
  219.    This works because it screws up the pattern match in
  220.    the routine `AfterSubString()' by removing the first
  221.    character from a string which might otherwise match.
  222.    e.g. it stops *.c from matching .c because the strings
  223.    which get passed to AfterSubString are `.c' (from *.c)
  224.    and `c' (from .c).
  225. 10.Isolate the next string sandwhiched between wild-cards
  226.    or string delimiters. Copy to buffer.
  227. 11.Make a note if we hit the end of wildstring in the process.
  228.    i.e. is this the end of the strings we're matching?
  229. 12.The call to this routine checks whether a match is
  230.    allowed between the isolated string and the comparison
  231.    string. If a match is allowed it updates the pointers
  232.    so that they point to the next characters after the
  233.    match. Otherwise it returns NULL.
  234.  
  235. AfterSubString()
  236.  
  237. 13. You can't find a string larger than big inside big!
  238.     (This could occur because of points 15. and 9.)
  239. 14. If the last wildcard was just to match a single
  240.     character then the string match must be anchored to
  241.     the current pointer locations.
  242. 15. If this is the end of the strings to be matched, then
  243.     make sure the match also correctly identifies which
  244.     pattern matches the END of the string. e.g.
  245.     to avoid confusion over *.abc in .abc.abc.abc
  246. 16. If the last wildcard was a * or none, then
  247.     use a forward floating comparision which can
  248.     skip over anyjunk characters looking for the next
  249.     occurrance of the string.
  250. 17. If this is the first two characters in the string
  251.     and there is no match, give up. This anchors the
  252.     floating match to the start to avoid
  253.     a*b matching xaxb by skipping over the first x!
  254. 18. If there is no match yet, there's no chance!
  255.  
  256. Test Data
  257. ----------
  258.  
  259. Wild String        Valid Match           No Match
  260. ------------       -----------          ----------
  261.  
  262. abcd                abcd
  263.  
  264. *mmm*               abcmmmabc            abcmmm
  265.                                          mmm
  266.  
  267. *j                  jjjj                 jjjjx
  268.  
  269. *.c                  a.c                  .c
  270.                      .c.c
  271. *y                   ayyyyyyy             ya
  272.                                            y
  273.  
  274. ?a                    aa                   aaa
  275.                       ba                   ab
  276.  
  277. ???a                  aaaa                 ab
  278.                       xyza                 xyzaa
  279. ???                   xyz                  ab
  280.                                            abcd
  281. *                     anything
  282. *.*                   anything.anything
  283. a*                    abc                   a
  284.                                             bad
  285. ?mmm?                 ammmb                 abcmmmd
  286.                                             mmm
  287. a*b                   axyzb                 xyz
  288.                       abbb                  axab
  289.  
  290. *******************************************************************/
  291.  
  292.  
  293. /* EOF */
  294.